----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    15:10:19 04/02/2008 
-- Design Name: 
-- Module Name:    STAGE_ID - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;

ENTITY STAGE_ID IS
  PORT (CLK       : IN  std_logic;
         RST      : IN  std_logic;
         IFID_NPC : IN  std_logic_vector(7 DOWNTO 0);
         IFID_IR  : IN  std_logic_vector(31 DOWNTO 0);
         WB_C     : IN  std_logic_vector(15 DOWNTO 0);
         WB_IND   : IN  std_logic_vector(4 DOWNTO 0);
         WB_WE    : IN  std_logic;
         IDEX_A   : OUT std_logic_vector(15 DOWNTO 0);
         IDEX_B   : OUT std_logic_vector(15 DOWNTO 0);
         IDEX_NPC : OUT std_logic_vector(7 DOWNTO 0);
         IDEX_IR  : OUT std_logic_vector(31 DOWNTO 0);
         IDEX_IMM : OUT std_logic_vector(15 DOWNTO 0)
         );
END STAGE_ID;

ARCHITECTURE Behavioral OF STAGE_ID IS
  TYPE   reg_file_type IS ARRAY (31 DOWNTO 0) OF std_logic_vector(15 DOWNTO 0);
  SIGNAL reg_file : reg_file_type;
BEGIN
  REG_FILE(0) <= (OTHERS => '0');       -- Register 0 is always 0
-- purpose: Performs instruction decoding
-- type : sequential
-- inputs : CLK, RST, IFID_NPC, IFID_IR
-- outputs: IDEX_A, IDEX_B, IDEX_NPC, IDEX_IR, IDEX_IMM
  PROCESS (CLK) IS
  BEGIN  -- PROCESS
    IF CLK'event AND CLK = '1' THEN     -- rising clock edge
      IF RST = '1' THEN                 -- synchronous reset (active high)
        IDEX_A   <= (OTHERS => '0');
        IDEX_B   <= (OTHERS => '0');
        IDEX_NPC <= (OTHERS => '0');
        IDEX_IR  <= (OTHERS => '0');
        IDEX_IMM <= (OTHERS => '0');
        FOR i IN 31 DOWNTO 1 LOOP
          REG_FILE(i) <= (OTHERS => '0');
        END LOOP;  -- i
      ELSE
        FOR i IN 31 DOWNTO 0 LOOP
          IF unsigned(IFID_IR(25 DOWNTO 21)) = i THEN
            IDEX_A <= REG_FILE(i);
          END IF;
        END LOOP;  -- i

        FOR i IN 31 DOWNTO 0 LOOP
          IF unsigned(IFID_IR(20 DOWNTO 16)) = i THEN
            IDEX_B <= REG_FILE(i);
          END IF;
        END LOOP;  -- i

        -- Write to all 31 full use (read/write) registers
        FOR i IN 31 DOWNTO 1 LOOP
          IF unsigned(WB_IND) = i AND WB_WE='1' THEN
            REG_FILE(i) <= WB_C;
          END IF;
        END LOOP;  -- i

        IDEX_NPC <= IFID_NPC;
        IDEX_IR  <= IFID_IR;
        IDEX_IMM <= IFID_IR(15 DOWNTO 0);
      END IF;
    END IF;
  END PROCESS;
END Behavioral;

